package nancal.mp.mvc.system

import io.swagger.annotations.Api
import io.swagger.annotations.ApiOperation
import nancal.mp.db.mongo.entity.sys.*
import nancal.mp.db.mongo.mor
import nbcp.base.annotation.*
import nbcp.base.annotation.mvc.*
import nbcp.base.comm.*
import nbcp.base.db.IdCodeName
import nbcp.base.extend.*
import nbcp.base.json.*
import nbcp.mvc.sys.*
import nbcp.myoql.db.db
import nbcp.myoql.db.excel.ExcelComponent
import nbcp.myoql.db.mongo.*

import org.springframework.web.bind.annotation.GetMapping
import org.springframework.web.bind.annotation.PostMapping
import org.springframework.web.bind.annotation.RequestMapping
import org.springframework.web.bind.annotation.RestController
import org.springframework.web.multipart.support.StandardMultipartHttpServletRequest
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletResponse

/**
 * Created by CodeGenerator at 2022-05-27 17:28:52
 */
@Api(description = "langResource", tags = arrayOf("LangResource"))
@RestController
@RequestMapping("/system/lang-resource")
class LangResourceAutoController {

    @ApiOperation("列表")
    @PostMapping("/list")
    fun list(
        id: String, //当列表列新一条后，刷新时使用
        productLineCode: String,
        key: String,
        value: String,
        @org.springframework.web.bind.annotation.RequestBody query: PagerModel<Any?>,
        request: HttpServletRequest
    ): ListResult<LangResource> {

        mor.sys.langResource.query()
            .apply {
                if (id.HasValue) {
                    this.where { it.id mongoEquals id }
                }

                if (productLineCode.HasValue) {
                    this.where { it.productLine.code mongoEquals productLineCode }
                }

                if (key.HasValue) {
                    this.where { it.key mongoLike key }
                }

                if (value.HasValue) {
                    this.linkOr({ it.en mongoLike value }, { it.cn mongoLike value })
                }
            }
            .withPager(query)
            .toListResult()
            .apply {
                return this;
            }
    }

    @ApiOperation("详情")
    @PostMapping("/detail/{id}")
    fun detail(
        @Require id: String,
        request: HttpServletRequest
    ): ApiResult<LangResource> {
        mor.sys.langResource.queryById(id)
            .toEntity()
            .apply {
                if (this == null) {
                    return ApiResult.error("找不到数据")
                }

                return ApiResult.of(this)
            }
    }

    @ApiOperation("更新")
    @GetMapping("/export/{type}")
    fun export(
        @Require productLineCode: String,
        lang: String,
        type: String,
        request: HttpServletRequest,
        response: HttpServletResponse
    ) {
        if (type.IsInItems("json", "property") == false) {
            throw RuntimeException("type 必须是 json,property 之一")
        }

        if (type == "property" && lang.isEmpty()) {
            throw RuntimeException("lang 不能为空")
        }

        mor.sys.langResource.query()
            .where { it.productLine.code mongoEquals productLineCode }
            .toList()
            .apply {

                response.setDownloadFileName(productLineCode + "." + type)

                if (type == "json") {
                    response.outputStream.write(this.map { it.ToJson() }.joinToString("\n").toByteArray(const.utf8))
                } else {
                    response.outputStream.write(this.map {
                        it.key + " = " + (if (lang == "en") it.en else it.cn).replace(
                            "\n",
                            "\\\n"
                        )
                    }.joinToString("\n").toByteArray(const.utf8))
                }
            }
    }


    @ApiOperation("更新")
    @PostMapping("/save")
    fun save(
        @org.springframework.web.bind.annotation.RequestBody entity: LangResource,
        request: HttpServletRequest
    ): ApiResult<String> {
        //鉴权
        var userId = request.UserId;

        mor.sys.langResource.updateWithEntity(entity)
            .withColumns(request.requestParameterKeys)
            .run {
                if (entity.id.HasValue) {
                    return@run this.execUpdate()
                } else {
                    return@run this.execInsert()
                }
            }
            .apply {
                if (this == 0) {
                    return ApiResult.error("更新失败")
                }

                return ApiResult.of(entity.id)
            }
    }

    @PostMapping("/import")
    fun import(request: StandardMultipartHttpServletRequest): JsonResult {
        var productLines = mor.dev.productLine.query().toList()

        var stream = request.getFirstUploadFileStream().readToMemoryStream()
        var excel = ExcelComponent { stream }
        excel.select()
            .setColumns("productLine.code", "key", "cn", "en")
            .getDataTable(LangResource::class.java)
            .rows
            .filter {
                return@filter it.productLine.code.HasValue && it.key.HasValue && (it.cn.HasValue || it.en.HasValue)
            }
            .forEach { ent ->
                var n = mor.sys.langResource.update()
                    .where { it.productLine.code mongoEquals ent.productLine.code }
                    .where { it.key mongoEquals ent.key }
                    .apply {
                        if (ent.cn.HasValue) {
                            this.set { it.cn to ent.cn }
                        }

                        if (ent.en.HasValue) {
                            this.set { it.en to ent.en }
                        }
                    }
                    .exec()

                if (n == 0) {
                    var productLine = productLines.firstOrNull { it.code == ent.productLine.code }
                    if (productLine == null) {
                        throw RuntimeException("找不到产品线编码 ${ent.productLine.code}")
                    }

                    var dbEnt = LangResource();
                    dbEnt.productLine = IdCodeName(productLine.id, productLine.code, productLine.name)
                    dbEnt.key = ent.key;
                    dbEnt.cn = ent.cn;
                    dbEnt.en = ent.en;

                    mor.sys.langResource.doInsert(dbEnt)

                    if (db.affectRowCount == 0) {
                        throw RuntimeException("插入失败")
                    }
                }
            }

        return JsonResult()
    }

    @ApiOperation("删除")
    @PostMapping("/delete/{id}")
    fun delete(
        @Require id: String,
        request: HttpServletRequest
    ): JsonResult {
        //鉴权
        var userId = request.UserId

        var entity = mor.sys.langResource.queryById(id).toEntity()
        if (entity == null) {
            return JsonResult.error("找不到数据")
        }

        mor.sys.langResource.deleteById(id)
            .exec()
            .apply {
                if (this == 0) {
                    return JsonResult.error("删除失败")
                }
                //实体上配置垃圾箱功能，可物理删除，会自动移到垃圾箱。
                return JsonResult()
            }
    }
}